package xyz.ibenben.zhongdian.system.service.elasticsearch.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.stereotype.Service;
import xyz.ibenben.zhongdian.common.constants.Constants;
import xyz.ibenben.zhongdian.system.entity.elasticsearch.BaseEntityForEs;
import xyz.ibenben.zhongdian.system.service.elasticsearch.ElasticsearchService;

import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @author chenjian
 */
@Slf4j
@Service
@SuppressWarnings("unchecked")
public abstract class AbstractElasticsearchServiceImpl<T extends BaseEntityForEs> implements ElasticsearchService<T> {
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;

    @Override
    public T selectByKey(Object key) {
        GetQuery getQuery = new GetQuery();
        getQuery.setId(key.toString());
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return elasticsearchTemplate.queryForObject(getQuery, entityClass);
    }

    @Override
    public void save(String type, T entity) {
        if (!elasticsearchTemplate.indexExists(Constants.INDEXNAME)) {
            elasticsearchTemplate.createIndex(Constants.INDEXNAME);
        }
        IndexQuery indexQuery = new IndexQueryBuilder().withIndexName(Constants.INDEXNAME)
                .withType(type).withId(entity.getId().toString()).withObject(entity).build();
        String result = elasticsearchTemplate.index(indexQuery);
        log.info("save result={}", result);
    }

    @Override
    public void delete(String type, Object key) {
        elasticsearchTemplate.delete(Constants.INDEXNAME, type, key.toString());
    }

    @Override
    public void updateAll(String type, T entity) {
        if (!elasticsearchTemplate.indexExists(Constants.INDEXNAME)) {
            elasticsearchTemplate.createIndex(Constants.INDEXNAME);
        }
        IndexQuery indexQuery = new IndexQueryBuilder().withIndexName(Constants.INDEXNAME)
                .withType(type).withId(entity.getId().toString()).withObject(entity).build();
        String result = elasticsearchTemplate.index(indexQuery);
        log.info("update result={}", result);
    }

    @Override
    public List<T> selectAll() {
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        SearchQuery searchQuery = new NativeSearchQueryBuilder().build();
        return elasticsearchTemplate.queryForList(searchQuery, entityClass);
    }

}
